import time
from typing import Any

from sqlalchemy.exc import IntegrityError
from sqlmodel import SQLModel, Field, Session, select

import user
from settings import engine, auto_session

class NameCardHolder(SQLModel, table=True):
    __tablename__ = "namecardholder"
    id:int = Field(primary_key=True, default=None)
    name:str = Field(default='')
    isinrecycle:bool = Field(nullable=False, default=False)
    user_id:int = Field(nullable=False, foreign_key="userinfo.id", ondelete="CASCADE")
    createtime:int = Field(nullable=False,default=0)

    def __init__(self, name:str='', isinrecycle:bool=False,**kwargs):
        """
        初始化NameCardHolder对象。

        参数:
            id (int): 名片夹ID，默认为0。
            name (str): 名片夹名称，默认为空字符串。
        """
        kwargs["name"] = name
        kwargs["isinrecycle"] = isinrecycle
        kwargs["createtime"] = int(time.time())
        super().__init__(**kwargs)
    def to_dict(self)->dict:
        return self.model_dump()


# SQLModel.metadata.create_all(engine)

@auto_session
def search_all_holder(user_id: int, isinrecycle: bool = False, session: Session = None) -> list[dict[str, Any]] | None:
    """
    根据用户ID查询所有名片夹信息。

    参数:
        user_id (int): 用户ID。

    返回:
        list[dict[str, Any]] | None: 名片夹信息列表，或None表示查询失败。
    """
    statement = select(NameCardHolder).where(NameCardHolder.user_id == user_id, NameCardHolder.isinrecycle == isinrecycle)
    result = session.exec(statement).all()
    ret =  [item.model_dump() for item in result]
    return ret

@auto_session
def search_1_holder_from_name(user_id: int, holdername: str, isinrecycle: bool = False, session: Session = None) -> int | None:
    """
    根据用户ID和名片夹名称查询名片夹ID。

    参数:
        user_id (int): 用户ID。
        holdername (str): 名片夹名称。

    返回:
        int | None: 名片夹ID, -1表示没找到名片夹，或None表示查询失败。
    """
    statement = (select(NameCardHolder)
                 .where(NameCardHolder.user_id == user_id,
                        NameCardHolder.isinrecycle == isinrecycle,
                        NameCardHolder.name == holdername))
    result = session.exec(statement).first()
    return result.id if result is not None else -1

@auto_session
def search_1_holder_from_id(user_id: int, holderid: int, isinrecycle: bool = False, session: Session = None) -> bool | None:
    """
    根据用户ID和名片夹ID查询名片夹是否存在。

    参数:
        user_id (int): 用户ID。
        holderid (int): 名片夹ID。

    返回:
        bool | None: 如果名片夹存在返回True，否则返回False；如果发生错误返回None。
    """
    statement = (select(NameCardHolder)
                 .where(NameCardHolder.user_id == user_id,
                        NameCardHolder.isinrecycle == isinrecycle,
                        NameCardHolder.id == holderid))
    return True if session.exec(statement).first() is not None else False

@auto_session
def insert_1_namecardholder(holder: NameCardHolder, session: Session = None) -> int | None:
    """
    插入一个新的名片夹信息。

    参数:
        user_id (int): 用户ID。
        holder (NameCardHolder): 名片夹对象。

    返回:
        int | None: 新插入的名片夹ID，-2表示名片夹已存在，None表示插入失败。
    """
    session.add(holder)
    try:
        session.commit()
        return holder.id
    except IntegrityError as e:
        session.rollback()
        print(f"插入数据时出错: {e}")
        return -2

@auto_session
def insert_some_namecardholder(namecardholders: list[NameCardHolder], session: Session = None) -> int | None:
    """
    批量插入多个名片夹信息。

    参数:
        user_id (int): 用户ID。
        namecardholders (list[NameCardHolder]): 包含多个名片夹对象的列表。

    返回:
        int | None: 成功插入的记录数，None表示插入失败。
    """
    success_count = 0
    for holder in namecardholders:
        if insert_1_namecardholder(holder = holder, session = session) or 0 > 0:
            success_count += 1
    return success_count

@auto_session
def update_1_namecardholder(holder: NameCardHolder, session: Session = None) -> int | None:
    """
    修改单个名片夹信息。

    参数:
        user_id (int): 用户ID。
        holder (NameCardHolder): 包含完整名片夹信息的对象。

    返回:
        int | None: 0表示修改成功，-2表示名片夹不存在，None表示操作失败。
    """
    if not session.get(NameCardHolder, holder.id):
        return -2
    try:
        session.merge(holder)
        session.commit()
        return 0
    except IntegrityError as e:
        session.rollback()
        print(f"修改数据时出错: {e}")
        return None

@auto_session
def search_all_recycle_holder(user_id: int, session: Session = None) -> list[dict[str, Any]] | None:
    """
    根据用户ID查询回收站中的名片夹信息。

    参数:
        user_id (int): 用户ID。

    返回:
        list[dict[str, Any]] | None: 回收站中的名片夹信息列表，或None表示查询失败。
    """
    return search_all_holder(user_id=user_id, isinrecycle=True,session=session)

@auto_session
def recycle_1_holder(holder_id: int, session: Session = None) -> int | None:
    """
    将指定名片夹移入回收站。

    参数:
        user_id (int): 用户ID。
        holder_id (int): 名片夹ID。

    返回:
        int | None: 0表示移入回收站成功，-2表示名片夹不存在，None表示操作失败。
    """
    holder = session.get(NameCardHolder, holder_id)
    if not holder:
        return -2
    holder.isinrecycle = True
    try:
        session.merge(holder)
        session.commit()
        return 0
    except IntegrityError as e:
        session.rollback()
        print(f"修改数据时出错: {e}")
        return None

@auto_session
def restore_1_holder(holder_id: int, session: Session = None) -> int | None:
    """
    将指定名片夹移出回收站。

    参数:
        user_id (int): 用户ID。
        holder_id (int): 名片夹ID。

    返回:
        int | None: 0表示移出回收站成功，None表示操作失败。
    """
    holder = session.get(NameCardHolder, holder_id)
    if not holder:
        return -2
    holder.isinrecycle = False
    try:
        session.merge(holder)
        session.commit()
        return 0
    except IntegrityError as e:
        session.rollback()
        print(f"修改数据时出错: {e}")
        return None

@auto_session
def delete_1_holder(holder_id: int, session: Session = None) -> int | None:
    """
    将指定名片夹从数据库中删除。

    参数:
        user_id (int): 用户ID。
        holder_id (int): 名片夹ID。

    返回:
        int | None: -2表示名片夹不存在，0表示删除成功，None表示出错
    """
    holder = session.get(NameCardHolder, holder_id)
    if not holder:
        return -2
    session.delete(holder)
    try:
        session.commit()
        return 0
    except IntegrityError as e:
        session.rollback()
        print(f"删除数据时出错: {e}")
        return None
